package com.njtoyo.taxi.admin.service.data.impl;

import cn.hutool.core.date.DateTime;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.logic.allowance.OrderLogic;
import com.njtoyo.taxi.admin.logic.allowance.RecommendationLogic;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverMarketing;
import com.njtoyo.taxi.admin.mapper.master.entity.DriverReward;
import com.njtoyo.taxi.admin.mapper.master.entity.Recommendation;
import com.njtoyo.taxi.admin.mapper.master.enums.CustomerFrom;
import com.njtoyo.taxi.admin.mapper.master.enums.DriverMarketingSituation;
import com.njtoyo.taxi.admin.mapper.master.enums.DriverRewardCategory;
import com.njtoyo.taxi.admin.mapper.master.enums.RecommendationPromoteChannel;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverMarketingMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.DriverRewardMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.RecommendationMapper;
import com.njtoyo.taxi.admin.rest.presenter.data.allowance.*;
import com.njtoyo.taxi.admin.rest.wrapper.data.allowance.AllowanceChartWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.data.allowance.AllowanceWrapper;
import com.njtoyo.taxi.admin.service.data.AllowanceDriverService;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.taxi.entity.common.RestResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@DS(Const.PRIMARY_DS)
public class AllowanceDriverServiceImpl implements AllowanceDriverService {

    @Autowired
    private DriverRewardMapper driverRewardMapper;

    @Autowired
    private OrderLogic orderLogic;

    @Autowired
    private RecommendationLogic recommendationLogic;

    @Autowired
    private RecommendationMapper recommendationMapper;

    @Autowired
    private DriverMarketingMapper driverMarketingMapper;

    @Override
    public RestResult<DriverAllowancePresenter> proportion(AdminUser adminUser, AllowanceWrapper wrapper) {
        QueryWrapper<DriverReward> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("created_at", wrapper.getStartTime(), wrapper.getEndTime())
                .select("category, IFNULL(SUM(amount), 0) AS total")
                .groupBy("category");

        List<Map<String, Object>> result = driverRewardMapper.selectMaps(queryWrapper);
        Map<Object, Object> resultMap = result.stream().collect(Collectors.toMap(p -> p.get("category"), p -> p.get("total")));

        DriverAllowancePresenter res = new DriverAllowancePresenter();
        // 高峰奖励
        res.setOnlineOrder((BigDecimal) resultMap.getOrDefault(DriverRewardCategory.onlineOrder.getCode(), BigDecimal.valueOf(0)));
        // 红包
        res.setRedPacket((BigDecimal) resultMap.getOrDefault(DriverRewardCategory.redPacket.getCode(), BigDecimal.valueOf(0)));
        // 推广奖励
        BigDecimal recommend1 = (BigDecimal) resultMap.getOrDefault(DriverRewardCategory.recommend.getCode(), BigDecimal.valueOf(0));
        BigDecimal recommend2 = (BigDecimal) resultMap.getOrDefault(DriverRewardCategory.recommendation_first_order_reward.getCode(), BigDecimal.valueOf(0));
        res.setRecommend(recommend1.add(recommend2));

        // 单数
        res.setOrderCount(orderLogic.getRideOrderCount(wrapper.getStartTime(), wrapper.getEndTime()).longValue());
        // 推广人数
        res.setRecommendCount(recommendationLogic.getDriverCount(wrapper.getStartTime(), wrapper.getEndTime()).longValue());

        return RestResult.success(res);
    }

    @Override
    public RestResult<DriverRedPacketAllowancePresenter> redPacket(AdminUser adminUser, AllowanceWrapper wrapper) {
        QueryWrapper<DriverReward> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category", DriverRewardCategory.redPacket)
                .between("created_at", wrapper.getStartTime(), wrapper.getEndTime())
                .select("is_verified, IFNULL(SUM(amount), 0) AS total")
                .groupBy("is_verified");

        List<Map<String, Object>> result = driverRewardMapper.selectMaps(queryWrapper);
        DriverRedPacketAllowancePresenter res = new DriverRedPacketAllowancePresenter();
        result.forEach(i -> {
            boolean isVerified = (boolean) i.get("isVerified");
            if (isVerified) {
                res.setOpened((BigDecimal) i.get("total"));
            } else {
                res.setUnopened((BigDecimal) i.get("total"));
            }
        });
        res.setOrderCount(orderLogic.getRideOrderCount(wrapper.getStartTime(), wrapper.getEndTime()).longValue());

        return RestResult.success(res);
    }

    @Override
    public RestResult<DriverRecommendAllowancePresenter> recommend(AdminUser adminUser, AllowanceWrapper wrapper) {
        List<DriverRewardSituationPresenter> result = driverRewardMapper.getAmountBySituation(wrapper.getStartTime(), wrapper.getEndTime(), DriverRewardCategory.recommend);
        DriverRecommendAllowancePresenter res = new DriverRecommendAllowancePresenter();
        res.setAppAmount(BigDecimal.valueOf(0));
        res.setWxminaAmount(BigDecimal.valueOf(0));
        result.forEach(i -> {
            if (i.getSituation().equals(DriverMarketingSituation.app_recommend) ||
                    i.getSituation().equals(DriverMarketingSituation.recommend_and_first_order) ||
                    i.getSituation().equals(DriverMarketingSituation.scan_recommend)) {
                res.setAppAmount(res.getAppAmount().add(i.getAmount()));
            }
            if (i.getSituation().equals(DriverMarketingSituation.wxmina_recommend) ||
                    i.getSituation().equals(DriverMarketingSituation.wxmina_scan_recommend)) {
                res.setWxminaAmount(res.getWxminaAmount().add(i.getAmount()));
            }
        });
        // 人数
        QueryWrapper<Recommendation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("promote_channel", RecommendationPromoteChannel.driver)
                .in("promote_platform", CustomerFrom.app, CustomerFrom.wxmina)
                .between("created_at", wrapper.getStartTime(), wrapper.getEndTime())
                .select("promote_platform, IFNULL(COUNT(*), 0) AS total")
                .groupBy("promote_platform");
        List<Map<String, Object>> customer = recommendationMapper.selectMaps(queryWrapper);
        customer.forEach(i -> {
            System.out.println(i);
            if (CustomerFrom.app.getCode() == (int) i.get("promotePlatform")) {
                res.setAppCount((Long) i.get("total"));
            }
            if (CustomerFrom.wxmina.getCode() == (int) i.get("promotePlatform")) {
                res.setWxminaCount((Long) i.get("total"));
            }
        });

        return RestResult.success(res);
    }

    @Override
    public RestResult<DriverPeakAllowancePresenter> peak(AdminUser adminUser, AllowanceWrapper wrapper) {
        DriverPeakAllowancePresenter res = new DriverPeakAllowancePresenter();

        // 高峰接单奖励
        QueryWrapper<DriverReward> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category", DriverRewardCategory.onlineOrder)
                .between("created_at", wrapper.getStartTime(), wrapper.getEndTime())
                .select("SUM(amount) AS amount, COUNT(*) AS count");
        List<Map<String, Object>> result = driverRewardMapper.selectMaps(queryWrapper);
        res.setAmount((BigDecimal) result.get(0).getOrDefault("amount", BigDecimal.valueOf(0)));
        res.setCount((Long) result.get(0).getOrDefault("count", 0));

        // 当前开通城市
        QueryWrapper<DriverMarketing> marketingQueryWrapper = new QueryWrapper<>();
        marketingQueryWrapper.eq("situation", DriverMarketingSituation.online_ride_fixed)
                .eq("is_active", 1)
                .le("started_at", DateTime.now())
                .ge("ended_at", DateTime.now())
                .select("DISTINCT driver_region_id");

        List<Object> cityCount = driverMarketingMapper.selectObjs(marketingQueryWrapper);
        res.setCityCount((long) cityCount.size());

        return RestResult.success(res);
    }

    @Override
    public RestResult<List<DriverAllowancePresenter>> chartProportion(AdminUser adminUser, AllowanceChartWrapper wrapper) {
        return null;
    }

    @Override
    public RestResult<List<DriverRedPacketAllowancePresenter>> chartRedPacket(AdminUser adminUser, AllowanceChartWrapper wrapper) {
        return null;
    }

    @Override
    public RestResult<List<DriverRecommendAllowancePresenter>> chartRecommend(AdminUser adminUser, AllowanceChartWrapper wrapper) {
        return null;
    }
}
